﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class CommondPoolManager
{
    KeyFrameTimeManager KeyFrameTimeMgr;

    Dictionary<long, LinkedList<BaseCommond>> serverCommonds  = new Dictionary<long, LinkedList<BaseCommond>>();
    public Dictionary<long, LinkedList<BaseCommond>> ServerCommonds { get { return serverCommonds; } }

    const int ServerCacheSize = 10;
    long ServerMinKeyFrameId = 0;
    Dictionary<long,LinkedList<BaseCommond>> ClientCacheCommonds =new Dictionary<long, LinkedList<BaseCommond>>();
    public CommondPoolManager(KeyFrameTimeManager timeMgr)
    { 
        KeyFrameTimeMgr = timeMgr;
    }

    public LinkedList<BaseCommond> GetLstCommondByKeyId(long keyFrameId)
    {
        if (serverCommonds.ContainsKey(keyFrameId))
        {
            return serverCommonds[keyFrameId];
        }
        return null;
    }
    public void ClientEmitCommond(BaseCommond cmd,long keyFrameId)
    {
        if (!ClientCacheCommonds.ContainsKey(keyFrameId))
        {
            this.ClientCacheCommonds.Add(keyFrameId,new LinkedList<BaseCommond>());
        }
    }

    public void Update()
    {
        SendClientCommond2Server();

        UpdateServerCommond();
    }

    void UpdateServerCommond()
    {
        if (serverCommonds.Count > ServerCacheSize)
        {
            if (!this.serverCommonds.Remove(ServerMinKeyFrameId))
            {
                long MinKF = long.MaxValue;
                foreach (long keyFrameid in serverCommonds.Keys)
                {
                    MinKF = keyFrameid < MinKF ? keyFrameid : MinKF;
                }
                this.ServerMinKeyFrameId = MinKF;
            }
            int FindSize = 1;
            while (FindSize < serverCommonds.Count)
            {
                if (serverCommonds.ContainsKey(FindSize + ServerMinKeyFrameId))
                {
                    ServerMinKeyFrameId += FindSize;
                    break;
                }
                FindSize++;
            }
        }
    }


    public void ServerPushCommond(BaseCommond cmd, long keyFrameId)
    {
        if (!serverCommonds.ContainsKey(keyFrameId))
        {
            serverCommonds.Add(keyFrameId,new LinkedList<BaseCommond>());
        }
        serverCommonds[keyFrameId].AddLast(cmd);
    }

    void SendClientCommond2Server()
    {
        List<long> rmkeys  = new List<long>();
        foreach (KeyValuePair<long,LinkedList<BaseCommond>> curCmd in this.serverCommonds)
        {
            if (curCmd.Key < KeyFrameTimeMgr.CurKeyFrameId)
            {
                foreach (BaseCommond cmd in curCmd.Value)
                {
                    cmd.SendToServer();
                }
                rmkeys.Add(curCmd.Key);
            }
        }
        for (int i=0;i<rmkeys.Count;i++)
        {
            this.serverCommonds.Remove(rmkeys[i]);
        }
    }
}
